﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using theeg.GeometryWpf;

namespace theeg.GraphWpf.Views
{
    public abstract class PresenterBase : Control
    {
        public static readonly RoutedEvent InputDownEvent = EventManager.RegisterRoutedEvent(
    "InputDown", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(PresenterBase));

        public event RoutedEventHandler InputDown
        {
            add { AddHandler(InputDownEvent, value); }
            remove { RemoveHandler(InputDownEvent, value); }
        }

        public static readonly RoutedEvent InputUpEvent = EventManager.RegisterRoutedEvent(
    "InputUp", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(PresenterBase));

        public event RoutedEventHandler InputUp
        {
            add { AddHandler(InputUpEvent, value); }
            remove { RemoveHandler(InputUpEvent, value); }
        }

        public static readonly RoutedEvent InputDoubleEvent = EventManager.RegisterRoutedEvent(
    "InputDouble", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(PresenterBase));

        public event RoutedEventHandler InputDouble
        {
            add { AddHandler(InputDoubleEvent, value); }
            remove { RemoveHandler(InputDoubleEvent, value); }
        }

        public abstract IHilbertTreeNode HilbertNode { get; }

        private DateTime _doubleClickTimeout;

        protected PresenterBase()
        {
            MouseDown += OnMouseDown;
            MouseUp += OnMouseUp;
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            base.OnMouseEnter(e);
            VisualStateManager.GoToState(this, "MouseOver", true);
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            base.OnMouseLeave(e);
            VisualStateManager.GoToState(this, "Normal", true);
        }

        private void OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            var args = new RoutedEventArgs { RoutedEvent = InputDownEvent, Source = HilbertNode };
            if (_doubleClickTimeout > DateTime.Now)
            {
                args.RoutedEvent = InputDoubleEvent;
                _doubleClickTimeout = DateTime.Now;
            }
            else
            {
                _doubleClickTimeout = DateTime.Now.AddMilliseconds(System.Windows.Forms.SystemInformation.DoubleClickTime);
            }
            RaiseEvent(args);
            if (args.Handled)
            {
                e.Handled = true;
            }
        }

        private void OnMouseUp(object sender, MouseButtonEventArgs e)
        {
            var args = new RoutedEventArgs { RoutedEvent = InputUpEvent, Source = HilbertNode };
            RaiseEvent(args);
            if (args.Handled)
            {
                e.Handled = true;
            }
        }
    }
}